package fwmpc.service.impl;

import fwmpc.interact.IWeiXinInteraction;
import fwmpc.resource.IWeiXinAttributeItem;
import fwmpc.store.IWeiXinAttributeStore;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;

import java.util.concurrent.TimeUnit;

/**
 * 类描述:  微信——H5业务处理处理Service
 *
 * @author 王雷
 * @version 1.0.0
 * @date 2021/1/21 0021 下午 10:15
 */
@Slf4j
public class WeiXinWebManagerService extends WeiXinAppletsManagerService {

    /**
     * 功能描述：微信——H5业务处理处理Service
     *
     * @param iWeiXinInteraction    微信通讯配置对象
     * @param iWeiXinAttributeStore 微信属性存储对象
     * @author : 王雷
     * @date : 2021/1/21 0021 下午 10:19
     */
    public WeiXinWebManagerService(IWeiXinInteraction iWeiXinInteraction
            , IWeiXinAttributeStore iWeiXinAttributeStore) {
        super(iWeiXinInteraction, iWeiXinAttributeStore);
    }

    protected static final String WEIXIN_TOKEN_TO_REIDS_KEY = "WeiXin_Token_";
    protected static final String WEIXIN_TICKET_TO_REIDS_KEY = "WeiXin_Ticket_";

    /**
     * 功能描述：获取Token
     *
     * @param appId 标识
     * @return 返回的数据结果；
     * @date : 2022/7/23 0023 上午 11:10
     */
    @Override
    public String giveToken(String appId) throws Exception {
        //获取Token
//        final IWeiXinAttributeItem iWeiXinAttributeItem = (StringUtils.isEmpty(appId)) ? giveWeiXinAttributeItem()
//                : giveWeiXinAttributeItem(appId);
        return giveWxToken((StringUtils.isEmpty(appId)) ? giveWeiXinAttributeItem()
                : giveWeiXinAttributeItem(appId));
    }

    /**
     * 功能名称: 远程调用——获取微信Token
     *
     * @param iWeiXinAttributeItem 微信基本属性项信息对象
     * @return 远程调用结果
     * @description:
     * @author: XXSD
     * @date: 2023-06-21 16:15
     */
    private String giveWxToken(IWeiXinAttributeItem iWeiXinAttributeItem) throws Exception {
        return giveRedisSerializableManager().giveValueByKeyToLock(WEIXIN_TOKEN_TO_REIDS_KEY + iWeiXinAttributeItem.giveAppId()
                , () -> iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveWebTokenUrl(), JSONObject.class
                        , requestHeaders -> {
                        }
                        , () -> null, parameter -> {
                            parameter.add("grant_type", "client_credential");
                            parameter.add("appid", iWeiXinAttributeItem.giveAppId());
                            parameter.add("secret", iWeiXinAttributeItem.giveAppSecret());
                        }, jsonObject -> {
                            log.debug("获取Token的结果为：{}", jsonObject);
                            return (jsonObject.get("access_token") == null) ? null : jsonObject.getString("access_token");
                        }), 1L, TimeUnit.HOURS);
    }

    /**
     * 功能描述：获取Ticket
     *
     * @param appId 标识
     * @return 返回的数据结果；
     * @date : 2022/7/23 0023 上午 11:10
     */
    @Override
    public String giveTicket(String appId) throws Exception {
        return giveWxTicket(appId);
    }

    /**
     * 功能名称: 远程获取微信Ticket
     *
     * @param appId       微信标识
     * @return Ticket结果
     * @description:
     * @author: XXSD
     * @date: 2023-06-21 16:24
     */
    protected String giveWxTicket(String appId) throws Exception {
        // platformKey
        return giveRedisSerializableManager().giveValueByKeyToLock(WEIXIN_TICKET_TO_REIDS_KEY + appId
                , () -> iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveWebTicketUrl(), JSONObject.class, requestHeaders -> {
                        }
                        , () -> null, parameter -> {
                            httpAlternatelyParameterPutTokenManager(parameter, appId);
                            parameter.add("type", "jsapi");
                        }, jsonObject -> {
                            log.debug("获取Ticket的结果为：{}", jsonObject);
                            return (jsonObject.get("ticket") == null) ? null : jsonObject.getString("ticket");
                        }), 1L, TimeUnit.HOURS);
    }

    /**
     * 功能描述：获取Token
     *
     * @return 返回的数据结果；
     * @date : 2022/7/23 0023 上午 11:10
     */
    @Override
    public String giveDefaultToken() throws Exception {
        return giveToken(null);
    }

    /**
     * 功能描述：获取Ticket
     *
     * @return 返回的数据结果；
     * @date : 2022/7/23 0023 上午 11:10
     */
    @Override
    public String giveDefaultTicket() throws Exception {
        return giveTicket(null);
    }

    /**
     * 功能描述：获取OpenId
     *
     * @param appId 应用标识
     * @param code  标识
     * @return 返回的数据结果；
     * @date : 2022/7/23 0023 上午 11:10
     */
    @Override
    public String giveOpenId(String appId, String code) throws Exception {
        final IWeiXinAttributeItem iWeiXinAttributeItem = iWeiXinAttributeStore.giveWeiXinCommonAttribute(appId);
        return iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveOpenIdUrl(), String.class, requestHeaders -> {
                }
                , () -> null, parameter -> {
                    parameter.add("appid", iWeiXinAttributeItem.giveAppId());
                    parameter.add("secret", iWeiXinAttributeItem.giveAppSecret());
                    parameter.add("code", code);
                    parameter.add("grant_type", "authorization_code");
                }, strDataValue -> {
                    log.debug("获取关注信息的结果为：{}", strDataValue);
                    try {
                        return JSONObject.fromObject(strDataValue).getString("openid");
                    } catch (Exception e) {
                        log.error("数据：{}；处理失败", strDataValue);
                    }
                    return null;
                });
    }

    /**
     * 功能描述：关注信息
     *
     * @param appId  标识
     * @param openId 顾客OpenId
     * @throws Exception 处理异常
     * @author : 王雷
     * @date : 2021/1/21 0021 上午 11:37
     */
    @Override
    public JSONObject giveFollowInformation(String appId, String openId) throws Exception {
        return iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveIsAttentionUrl(), JSONObject.class, requestHeaders -> {
                }
                , () -> null, parameter -> {
                    httpAlternatelyParameterPutTokenManager(parameter, appId);
                    parameter.add("openid", openId);
                }, jsonObject -> {
                    log.debug("获取关注信息的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }

    /**
     * 功能描述：微信访问地址——获取素材总数
     *
     * @param appId 标识
     * @author : 王雷
     * @date : 2021/1/22 0022 下午 8:24
     */
    @Override
    public JSONObject giveMaterialCount(String appId) throws Exception {
        return iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveMaterialCountUrl(), JSONObject.class, requestHeaders -> {
                }
                , () -> null, parameter -> httpAlternatelyParameterPutTokenManager(parameter, appId), jsonObject -> {
                    log.debug("获取素材总数的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }

    /**
     * 功能描述：微信访问地址——获取素材列表
     *
     * @param appId        标识
     * @param parameterMap 参数
     * @author : 王雷
     * @date : 2021/1/22 0022 下午 8:24
     */
    @Override
    public <PM> JSONObject giveMaterialData(String appId, PM parameterMap) throws Exception {
        return iWeiXinInteraction.httpByPost(iWeiXinAttributeStore.giveMaterialDataUrl(), JSONObject.class, requestHeaders -> {
                    requestHeaders.setContentType(MediaType.APPLICATION_JSON);
                }
                , () -> parameterMap, parameter -> httpAlternatelyParameterPutTokenManager(parameter, appId), jsonObject -> {
                    log.debug("获取素材列表的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }

    /**
     * 功能描述：微信访问地址——获取微信菜单
     *
     * @param appId 标识
     * @author : 王雷
     * @date : 2021/1/22 0022 下午 8:24
     */
    @Override
    public JSONObject giveWxMenu(String appId) throws Exception {
        return iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveWxMenuUrl(), JSONObject.class, requestHeaders -> {
                }
                , () -> null, parameter -> httpAlternatelyParameterPutTokenManager(parameter, appId), jsonObject -> {
                    log.debug("获取素材总数的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }

    /**
     * 功能描述：微信访问地址——更新微信菜单
     *
     * @param appId        标识
     * @param parameterMap 参数
     * @author : 王雷
     * @date : 2021/1/22 0022 下午 8:24
     */
    @Override
    public <PM> JSONObject updateWxMenu(String appId, PM parameterMap) throws Exception {
        return iWeiXinInteraction.httpByPost(iWeiXinAttributeStore.giveUpdateWxMenuUrl(), JSONObject.class, requestHeaders -> {
                    requestHeaders.setContentType(MediaType.APPLICATION_JSON);
                }
                , () -> parameterMap, parameter -> {
                    httpAlternatelyParameterPutTokenManager(parameter, appId);
                }, jsonObject -> {
                    log.debug("获取素材列表的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }

    /**
     * 功能描述：微信访问地址——批量为用户打标签
     *
     * @param appId        标识
     * @param parameterMap 参数
     * @author : 王雷
     * @date : 2021/1/22 0022 下午 8:24
     */
    @Override
    public <PM> JSONObject batchUserByTag(String appId, PM parameterMap) throws Exception {
        return iWeiXinInteraction.httpByPost(iWeiXinAttributeStore.giveBatchUserByTagUrl(), JSONObject.class, requestHeaders -> {
                    requestHeaders.setContentType(MediaType.APPLICATION_JSON);
                }
                , () -> parameterMap, parameter -> {
                    httpAlternatelyParameterPutTokenManager(parameter, appId);
                }, jsonObject -> {
                    log.debug("批量为用户打标签的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }

    /**
     * 功能描述：微信访问地址——获取微信用户信息
     *
     * @param appId  标识
     * @param openId 用户OpenId
     * @author : 王雷
     * @date : 2021/1/22 0022 下午 8:24
     */
    @Override
    public JSONObject giveUserMessage(String appId, String openId) throws Exception {
        return iWeiXinInteraction.httpByGet(iWeiXinAttributeStore.giveUserInfoUrl(), JSONObject.class, requestHeaders -> {
                }
                , () -> null, parameter -> {
                    httpAlternatelyParameterPutTokenManager(parameter, appId);
                    parameter.add("openid", openId);
                    parameter.add("lang", "zh_CN");
                }, jsonObject -> {
                    log.debug("获取素材总数的结果为：{}", jsonObject);
                    return jsonObject;
                });
    }
}
